package org.itec.yeast.db;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ResourceBundle;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jolbox.bonecp.BoneCP;
import com.jolbox.bonecp.BoneCPConfig;
import com.jolbox.bonecp.Statistics;

/**
 * 数据库连接池BoneCP的封装使用 主要是实现数据库连接的配置信息（驱动类、JDBC URL、用户名和密码）独立设置 ,<br />
 * 采用单例模式，保证系统中只有一个数据库连接池。
 * 
 */
public class DBConnectionPool {

	private static final Logger log = LoggerFactory
			.getLogger(DBConnectionPool.class);

	/**
	 * BoneCP配置类
	 */
	private BoneCPConfig config = null;

	/**
	 * BoneCP连接池
	 */
	private BoneCP connectionPool = null;

	/**
	 * 唯一实例
	 */
	private static final DBConnectionPool pool = new DBConnectionPool();

	public static DBConnectionPool getInstance() {

		return pool;
	}

	/**
	 * 私有构造器，初始化连接池
	 */
	private DBConnectionPool() {

		/**
		 * 读取数据库相关配置 将数据库的配置从数据库连接池中独立出来，解耦，方便单独设置和修改
		 */
		ResourceBundle bundle = ResourceBundle.getBundle("database");
		String driverClass = bundle.getString("jdbc.driverClass");
		String jdbcURL = bundle.getString("jdbc.url");
		String username = bundle.getString("jdbc.username");
		String password = bundle.getString("jdbc.password");

		if (driverClass == null || "".equals(driverClass) || jdbcURL == null
				|| "".equals(jdbcURL) || username == null
				|| "".equals(username) || password == null
				|| "".equals(password)) {
			log.error("数据库配置信息有误，请检查 database.properties文件。");
			return;
		}

		try {
			/*
			 * 谨记：使用BoneCPConfig默认的构造器时，代码中明确了以下操作：
			 * loadProperties("bonecp-default-config.xml"); //配置默认的属性
			 * loadProperties("bonecp-config.xml"); //配置用户指定的属性，与默认属性相同的就覆盖之。
			 * 但实现中存在一个问题，参照方法：protected void loadProperties(String filename);
			 * // BoneCPConfig.class line:1621, version:0.7.1 rc3
			 * 获取URI的方式存在bug，在IDE中运行正常，但部署到Tomcat中会因为classpath值不合适而找不到相应配置文件。
			 * 参考：
			 * http://wiki.apache.org/tomcat/HowTo#How_do_I_load_a_properties_file
			 * .3F
			 */
			config = new BoneCPConfig("YeastDBPoolConf");
			config.setJdbcUrl(jdbcURL);
			config.setUsername(username);
			config.setPassword(password);

			// 注册JDBC驱动程序
			Class.forName(driverClass);

			// 初始化连接池
			connectionPool = new BoneCP(config);
			log.info("BoneCP 连接池初始化成功! 配置信息：" + config.toString());
		} catch (Exception e) {
			e.printStackTrace();
			log.error("BoneCP 连接池初始化失败： ", e);
		}
	}

	/**
	 * 关闭连接池
	 */
	public void close() {
		connectionPool.close();
	}

	/**
	 * 从连接池里获取数据库连接
	 * 
	 * @return
	 * @throws SQLException
	 */
	public Connection getConnection() throws SQLException {
		return connectionPool.getConnection();
	}

	/**
	 * 打印连接池使用信息
	 */
	public void printPoolStatus() {
		Statistics stat = connectionPool.getStatistics();
		log.info("连接池名称：" + config.getPoolName() + ", 空闲连接数 / 总连接数 = "
				+ stat.getTotalFree() + " / "
				+ stat.getTotalCreatedConnections());
	}

//	 public static void main(String[] args) {
//		 DBConnectionPool pool = DBConnectionPool.getInstance();
//		 pool.printPoolStatus();
//		 pool.close();
//	 }
}
